'''此模块用于优化对xlsx及xls文件进行sheet获取、统一读取、自动推测列标题位置功能进行优化。

1.以统一方式读取xls和xlsx文件中的指定内容，并以列表的形式返回。  
2.自动检测给定路的excel文件中，表标题位置、列标题名称位置。   
3.获取xls和xlsx文件中指定路径下的工作簿文件中sheet列表。    
'''

import logging
import pandas as pd

mylog = logging.getLogger()

def count_validate(data):
    '''获取data列表中，每行有效数据的个数。
    data：要统计有效数据的列表
    返回：表示每行有效数据个数的数组
    '''
    lens = []
    for index,line in data.iterrows():
        count = 0
        for item in line.tolist():
            if item and not pd.isna(item):
                count += 1
        lens.append(count)
    return lens

def strip_row(line):
    '''去除一行数据中末尾无效内容。
    line：要处理的列表行。
    '''
    line.reverse()
    for i,item in enumerate(line):
        if item:
            #item为有效数字
            #当item为string时判断是否包含Unnamed
            if type(item) != str:
                line.reverse()
                return line[:len(line)-i]
            else:
                if item.find('Unnamed')==-1:
                    line.reverse()
                    return line[:len(line)-i]
                else:
                    continue
                    
    return []


class ExcelReader():
    '''此类主要用于实现xlsx文件和xls文件统一读取、sheet信息获取、自动推测列标题。通过减少读取文件次数提高效率。
    '''
    def __init__(self,path):
        self._p = path
        
        mylog.debug('读取Excel文件：[{}]'.format(path))
        self.wb_data = pd.read_excel(path,header=None,sheet_name=None,nrows=10)

        mylog.info('文件加载成功！')

    def getSheetNames(self):
        '''获取xls和xlsx文件中指定路径下的工作簿文件中sheet列表。
        sheetlist:当前工作簿中包含的sheet列表。
        '''

        sheetlist = list(self.wb_data.keys())

        return sheetlist

    
    def detectHeader(self,sheetname=None,max_row=10):
        '''自动检测给定路的excel文件中，表标题位置、表列标题名称位置。。
        sheetname:要自动检测的excel表的表名。若为None则表示默认打开第一个表。
        max_row:检测表头部范围，默认在前10行范围内检测
        '''
        mylog.debug('检测表[{}]的头部'.format(sheetname))
        if not sheetname:
            sheetname = self.getSheetNames()[0]
        data = self.wb_data[sheetname]
        lens = count_validate(data)
        col_index = 0
        max_items = 0
        for i,item in enumerate(lens):
            if item > max_items:
                col_index = i
                max_items = item
        columns = strip_row(data.loc[col_index,:].tolist())
        mylog.debug('header index:{}'.format(col_index))
        mylog.debug('header columns:{}'.format(columns))

        data = pd.read_excel(self._p,sheet_name=sheetname,header=col_index,nrows=max_row)
        columns_type = []
        for col in columns:
            columns_type.append(str(data[col].dtype))
                
        table = {
            'columns':columns,
            'columns_type':columns_type,
            'columns_index':col_index,
        }
        mylog.info('文件头部信息：{}'.format(table))
    
        return table